import {FlatList, FlatListProps, RefreshControl, Text, ViewStyle} from 'react-native'
import NoData from '@path/components/NoData'
import {px2dp} from '@path/config/system'
import Theme from '@path/config/theme'
import Locale from '@path/locale'
import React from 'react'
import {ThemeText} from '@path/components/ThemeComponents'

interface DataListProps extends FlatListProps<any> {
  getList?: (page: number, size: number) => Promise<any>
  placeholder?: any[]
  size?: number
  isPageable?: boolean
  placeholderStyle?: ViewStyle
  ref?: DataList
  isShowRefresh?: boolean
  extraRefresh?: () => any
  onDataUpdate?: (data: any[], isNoMore: boolean) => any
}

const StartPage = 1

/**
 * 通用列表组件 自身维护分页
 */
export default class DataList extends React.Component<DataListProps> {
  constructor(props: any) {
    super(props)
  }

  state = {
    data: [],
    placeholder: this.props.placeholder ?? [],
    page: StartPage,
    isLoading: false,
    isLoadingMore: false,
    isNoMore: false,
    size: this.props.size,
  }

  deepRef?: FlatList

  static defaultProps: DataListProps = {
    isPageable: true,
    placeholderStyle: {},
    size: 20,
    isShowRefresh: true,
  }

  componentDidMount() {
    this._getList()
  }

  //提供给外部刷新
  refresh = (isClearData: boolean = false) => {
    this.setState(
      {
        page: 1,
        isNoMore: false,
        data: isClearData ? [] : this.state.data,
      },
      () => {
        this._getList()
      },
    )
  }

  //提供给外部获取数据
  getData = () => {
    return this.state.data
  }

  //更新data 可用于局部更新
  update = (data: any[]) => {
    this.setState({data})
  }

  _onDataUpdate = () => {
    typeof this.props.onDataUpdate === 'function' && this.props.onDataUpdate(this.state.data, this.state.isNoMore)
  }

  getDeepRef = () => {
    return this.deepRef
  }

  _getList = (page = this.state.page, size = this.state.size) => {
    if (this.state.isLoading || this.state.isNoMore || typeof this.props.getList !== 'function') {
      return
    }
    this.setState(
      {
        isLoading: true,
      },
      () => {
        this.props
          ?.getList(page, size)
          .then((res) => {
            this.setState({
              data: page === StartPage ? res : this.state.data.concat(res),
              isNoMore: !this.props.isPageable || res.length < size || res.length === 0,
            })
          })
          .catch(() => {
            this.setState({
              isNoMore: true,
            })
          })
          .finally(() => {
            this.setState({
              isLoading: false,
              isLoadingMore: false,
            })
          })
      },
    )
  }

  _handleFooterText = () => {
    if (this.state.isLoadingMore) {
      return Locale.getString('common.loading')
    } else if (this.state.data?.length && this.state.isNoMore) {
      return Locale.getString('common.no_more')
    } else {
      return ''
    }
  }

  render() {
    return (
      <FlatList
        data={this.state.data.length || this.state.isNoMore ? this.state.data : this.state.placeholder}
        renderItem={this.props.renderItem}
        ListEmptyComponent={
          !this.state.isLoading && (
            <NoData
              style={{
                marginTop: px2dp(50),
                paddingVertical: px2dp(20),
                ...this.props.placeholderStyle,
              }}
            />
          )
        }
        refreshControl={
          this.props.isShowRefresh ? (
            <RefreshControl
              refreshing={this.state.isLoading && !this.state.isLoadingMore}
              onRefresh={() => {
                this.setState(
                  {
                    page: 1,
                    isNoMore: false,
                  },
                  () => {
                    this._getList()
                    typeof this.props.extraRefresh === 'function' && this.props.extraRefresh()
                  },
                )
              }}
            />
          ) : undefined
        }
        onEndReachedThreshold={0.1}
        onEndReached={() => {
          if (this.state.isLoading || this.state.isNoMore) {
            return
          }

          this.setState(
            {
              page: this.state.page + 1,
              isLoadingMore: true,
            },
            () => {
              this._getList()
            },
          )
        }}
        ListFooterComponent={() => {
          return this.props.isPageable && this.state.data.length && this._handleFooterText() ? (
            <ThemeText
              style={{
                paddingVertical: px2dp(20),
                alignSelf: 'center',
                color: Theme.getThemeColor('text_tip'),
              }}>
              {this._handleFooterText()}
            </ThemeText>
          ) : null
        }}
        windowSize={300}
        {...this.props}
        ref={(ref) => {
          this.deepRef = ref
        }}
      />
    )
  }
}
